package com.gugee.tiktok.web.service;

import cn.hutool.core.date.DateUtil;
import com.gugee.tiktok.web.dto.RankSearchData;
import com.gugee.tiktok.web.dto.RankingFollowerResponse;
import com.gugee.tiktok.web.dto.RankingResponse;
import com.gugee.tiktok.web.repository.*;
import com.gugee.tiktok.web.model.mysql.Ranking;
import com.gugee.tiktok.web.model.mysql.RankingFollowers;
import com.xiguaji.boot.toolkit.jdbc.Page;
import lombok.val;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
public class RankingService {

    @Autowired
    RankingRepository rankingRepository;

    @Autowired
    RankingFollowersRepository rankingFollowersRepository;

    @Autowired
    RankingEnterpriseRepository rankingEnterpriseRepository;

    @Autowired
    RankingRegionRepository rankingRegionRepository;

    @Autowired
    BloggerCollectionRepository bloggerCollectionRepository;

    DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MMM dd, yyyy", Locale.ENGLISH);

    //===================================================博主排行榜 START===================================================

    public Page<RankingResponse> getPageRanking(RankSearchData searchData, Long userId){
        val listForPage = rankingRepository.getListForPage(searchData);
        if(null != userId){
            listForPage.getList().forEach( l->{
                val bloggerCollectionOptional = bloggerCollectionRepository.findByBloggerIdAndUserId(l.getUid(),userId);

                if(bloggerCollectionOptional.isPresent()){
                    l.setFavorite(true);
                    l.setCollectId(bloggerCollectionOptional.get().getId());
                }
            });
        }
        return listForPage;
    }



    public List<Ranking> getRankingList(RankSearchData searchData, Integer count){
        return rankingRepository.getList(searchData,count);
    }



    public Map<String,Long> getRankingUpdateTime(){
        Map<String,Long> result = new HashMap<>();
        result.put("daily",rankingRepository.findUpdateTime(1));
        result.put("weekly",rankingRepository.findUpdateTime(2));
        result.put("monthly",rankingRepository.findUpdateTime(3));
        return result;
    }



    public Map<String,Object> getRankingDate(int dayStart,int weekStart,int monthStart){
        Map<String,Object> ret = new HashMap<>();
        val dailyDate = getDailyDate(rankingRepository.findBelongDate(1, dayStart));
        val weeklyDate = getWeeklyDate(rankingRepository.findBelongDate(2, weekStart));
        val monthlyDate = getMonthlyDate(rankingRepository.findBelongDate(3, monthStart));
        ret.put("dailyDate",dailyDate);
        ret.put("weeklyDate",weeklyDate);
        ret.put("monthlyDate",monthlyDate);
        return ret;
    }



    /**
     * 获取播主排名
     * @param uid 播主id
     * @param rankingType 日期排名类型（1：日，2：周，3：月）
     * @param bloggerType 播主类型
     * @param date 日期
     * @return
     */
    public Ranking getBloggerRanking(long uid, int rankingType,int bloggerType, int date){
        val ranking = rankingRepository.findBloggerRanking(uid, rankingType, bloggerType, date);
        return ranking.isPresent() ? ranking.get() : null;
    }

    //===================================================博主排行榜 END===================================================



    //===================================================博主涨粉排行榜 START===================================================
    public Map<String,Long> getRankingFollowerUpdateTime(){
        Map<String,Long> result = new HashMap<>();
        result.put("daily",rankingFollowersRepository.findUpdateTime(1));
        result.put("weekly",rankingFollowersRepository.findUpdateTime(2));
        result.put("monthly",rankingFollowersRepository.findUpdateTime(3));
        return result;
    }

    public Map<String,Object> getRankingFollowerDate(int dayStart,int weekStart,int monthStart){
        Map<String,Object> ret = new HashMap<>();
        val dailyDate = getDailyDate(rankingFollowersRepository.findBelongDate(1, dayStart));
        val weeklyDate = getWeeklyDate(rankingFollowersRepository.findBelongDate(2, weekStart));
        val monthlyDate = getMonthlyDate(rankingFollowersRepository.findBelongDate(3, monthStart));
        ret.put("dailyDate",dailyDate);
        ret.put("weeklyDate",weeklyDate);
        ret.put("monthlyDate",monthlyDate);
        return ret;
    }



    public Page<RankingFollowerResponse> getPageRankingFollowers(RankSearchData searchData, Long userId){
        val listForPage = rankingFollowersRepository.getListForPage(searchData);

        if(null != userId){
            listForPage.getList().forEach( l->{
                val bloggerCollectionOptional = bloggerCollectionRepository.findByBloggerIdAndUserId(l.getUid(), userId);

                if(bloggerCollectionOptional.isPresent()){
                    l.setFavorite(true);
                    l.setCollectId(bloggerCollectionOptional.get().getId());
                }
            });
        }
        return listForPage;
    }

    public List<RankingFollowers> getRankingFollowersList(RankSearchData searchData, Integer count){
        return rankingFollowersRepository.getList(searchData,count);
    }

    //===================================================博主涨粉排行榜 END===================================================


    //===================================================博主企业排行榜 START===================================================
    public Page<RankingResponse> getPageRankingEnterprise(RankSearchData searchData, Long userId){
        val listForPage = rankingEnterpriseRepository.getListForPage(searchData);

        if(null != userId){
            listForPage.getList().forEach( l->{
                val bloggerCollectionOptional = bloggerCollectionRepository.findByBloggerIdAndUserId(l.getUid(),userId);

                if(bloggerCollectionOptional.isPresent()){
                    l.setFavorite(true);
                    l.setCollectId(bloggerCollectionOptional.get().getId());
                }
            });
        }


        return listForPage;
    }



    public List<Ranking> getRankingEnterpriseList(RankSearchData searchData,Integer count){
        return rankingEnterpriseRepository.getList(searchData,count);
    }



    public Map<String,Long> getRankingEnterpriseUpdateTime(){
        Map<String,Long> result = new HashMap<>();
        result.put("daily",rankingEnterpriseRepository.findUpdateTime(1));
        result.put("weekly",rankingEnterpriseRepository.findUpdateTime(2));
        result.put("monthly",rankingEnterpriseRepository.findUpdateTime(3));
        return result;
    }



    public Map<String,Object> getRankingEnterpriseDate(int dayStart,int weekStart,int monthStart){
        Map<String,Object> ret = new HashMap<>();
        val dailyDate = getDailyDate(rankingEnterpriseRepository.findBelongDate(1, dayStart));
        val weeklyDate = getWeeklyDate(rankingEnterpriseRepository.findBelongDate(2, weekStart));
        val monthlyDate = getMonthlyDate(rankingEnterpriseRepository.findBelongDate(3, monthStart));
        ret.put("dailyDate",dailyDate);
        ret.put("weeklyDate",weeklyDate);
        ret.put("monthlyDate",monthlyDate);
        return ret;
    }

    //===================================================博主企业排行榜 END===================================================


    //===================================================博主国家排行榜 START===================================================
    public Page<RankingResponse> getPageRankingRegion(RankSearchData searchData, Long userId){
        val listForPage = rankingRegionRepository.getListForPage(searchData);
        if(null != userId){
            listForPage.getList().forEach( l->{
                val bloggerCollectionOptional = bloggerCollectionRepository.findByBloggerIdAndUserId(l.getUid(),userId);

                if(bloggerCollectionOptional.isPresent()){
                    l.setFavorite(true);
                    l.setCollectId(bloggerCollectionOptional.get().getId());
                }
            });
        }
        return listForPage;
    }



    public List<Ranking> getRankingRegionList(RankSearchData searchData,Integer count){
        return rankingRegionRepository.getList(searchData,count);
    }



    public Map<String,Long> getRankingRegionUpdateTime(){
        Map<String,Long> result = new HashMap<>();
        result.put("daily",rankingRegionRepository.findUpdateTime(1));
        result.put("weekly",rankingRegionRepository.findUpdateTime(2));
        result.put("monthly",rankingRegionRepository.findUpdateTime(3));
        return result;
    }



    public Map<String,Object> getRankingRegionDate(int dayStart,int weekStart,int monthStart){
        Map<String,Object> ret = new HashMap<>();
        val dailyDate = getDailyDate(rankingRegionRepository.findBelongDate(1, dayStart));
        val weeklyDate = getWeeklyDate(rankingRegionRepository.findBelongDate(2, weekStart));
        val monthlyDate = getMonthlyDate(rankingRegionRepository.findBelongDate(3, monthStart));
        ret.put("dailyDate",dailyDate);
        ret.put("weeklyDate",weeklyDate);
        ret.put("monthlyDate",monthlyDate);
        return ret;
    }

    //===================================================博主国家排行榜 END===================================================


    private List<Map<String,Object>> getDailyDate(List<Integer> dailyDates){
        List<Map<String,Object>> datas = new ArrayList<>();

        for (Integer dailyDate : dailyDates) {
            Map<String,Object> data = new HashMap<>();
            data.put("dateCode",dailyDate);
            data.put("dateDesc",DateUtil.parseLocalDateTime(dailyDate.toString(),"yyyyMMdd").format(dateTimeFormatter));
            datas.add(data);
        }
        return datas;
    }

    private List<Map<String,Object>> getWeeklyDate(List<Integer> weeklyDates){
        List<Map<String,Object>> datas = new ArrayList<>();

        for (Integer weekly : weeklyDates) {
            Map<String,Object> data = new HashMap<>();
            data.put("dateCode",weekly);
            var startDay = DateUtil.parseLocalDateTime(weekly.toString(),"yyyyMMdd");
            var endDay = startDay.plusDays(6);

            if(startDay.format(DateTimeFormatter.ofPattern("yyyy")).equals(endDay.format(DateTimeFormatter.ofPattern("yyyy")))){
                data.put("dateDesc",startDay.format(DateTimeFormatter.ofPattern("MMM dd", Locale.ENGLISH))+"-"+endDay.format(dateTimeFormatter));
            }else {
                data.put("dateDesc",startDay.format(dateTimeFormatter)+"-"+endDay.format(dateTimeFormatter));
            }
            datas.add(data);
        }
        return datas;
    }

    private List<Map<String,Object>> getMonthlyDate(List<Integer> monthlyDates){
        List<Map<String,Object>> datas = new ArrayList<>();

        for (Integer monthly : monthlyDates) {
            Map<String,Object> data = new HashMap<>();
            data.put("dateCode",monthly);
            var startDay = DateUtil.parseLocalDateTime(monthly.toString(),"yyyyMMdd");
            data.put("dateDesc",startDay.format(DateTimeFormatter.ofPattern("MMMM yyyy", Locale.ENGLISH)));
            datas.add(data);
        }
        return datas;
    }
}
